/**
 * $Revision$
 * $Date$
 *
 * Copyright (C) https://gitee.com/baibaiclouds/platform loon. All rights reserved.
 * <p>
 * This software is the confidential and proprietary information of loon.
 * You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the agreements you entered into with loon.
 * 
 * Modified history:
 *   Administrator  2019年9月21日 上午10:32:39  created
 */
package com.desktop.web.service.guacamole;

import java.util.HashMap;
import java.util.Map;

import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;

import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.GuacamoleSocket;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.net.InetGuacamoleSocket;
import org.apache.guacamole.net.SimpleGuacamoleTunnel;
import org.apache.guacamole.protocol.ConfiguredGuacamoleSocket;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
import org.apache.guacamole.websocket.GuacamoleWebSocketTunnelEndpoint;
import org.springframework.util.StringUtils;

import com.desktop.web.core.comenum.RemoteProtocolType;
import com.desktop.web.core.comenum.Status;
import com.desktop.web.core.exception.BusinessException;
import com.desktop.web.service.auditvideo.AuditVideoService;
import com.desktop.web.service.file.FileService;
import com.desktop.web.service.remotecpe.NatInfo;
import com.desktop.web.service.remotecpe.NatService;
import com.desktop.web.service.remotecpe.RemotecpeService;
import com.desktop.web.service.remotecpe.VirtulNatService;

/**
 * 
 *
 * @author baibai
 */
public class LoonGuacamoleWebSocketTunnelEndpoint extends GuacamoleWebSocketTunnelEndpoint {

    public static String GUAC_HOSTNAME = "";
    public static Integer GUAC_PORT = 0;
    public static NatService natService;
    public static VirtulNatService virtulNatService;
    public static FileService fileService;
    public static RemotecpeService remotecpeService;
    public static AuditVideoService auditVideoService;

    /*
     * @see
     * org.apache.guacamole.websocket.GuacamoleWebSocketTunnelEndpoint#createTunnel(javax.websocket.
     * Session, javax.websocket.EndpointConfig)
     */
    @Override
    protected GuacamoleTunnel createTunnel(Session session, EndpointConfig endpointConfig) throws GuacamoleException {

        try {
            Map<String, String> params = getParams(session.getQueryString());
            if (params.isEmpty()) {
                throw new BusinessException("参数错误");
            }

            String uuid = params.get("uuid");
            String width = params.get("width");
            String height = params.get("height");

            if (StringUtils.isEmpty(uuid)) {
                throw new BusinessException("参数错误");
            }

            NatInfo natInfo = virtulNatService.getNatInfoByUUID(uuid);
            if (natInfo == null) {
                natInfo = natService.getPortInfoByUUID(uuid);
            }

            if (natInfo == null) {
                throw new BusinessException("参数错误");
            }

            GuacamoleConfiguration config = new GuacamoleConfiguration();
            config.setProtocol(natInfo.getTunnetType().toString().toLowerCase());
            config.setParameter("color-depth", natInfo.getColor().getColor() + "");
            config.setParameter("port", natInfo.getRemotePort().toString());
            config.setParameter("hostname", natInfo.getRemoteIp());
            config.setParameter("password", natInfo.getPassword());
            config.setParameter("recording-path", "/home/guacd/file");
            config.setParameter("recording-name", uuid);
            config.setParameter("width", width);
            config.setParameter("height", height);
            config.setParameter("resize-method", "reconnect");
            config.setParameter("enable-wallpaper", "true");// 开启桌面壁纸渲染
            config.setParameter("enable-theming", "true");
            config.setParameter("enable-font-smoothing", "true");// 文本将以平滑的边缘呈现
            config.setParameter("enable-desktop-composition", "true");

            if (natInfo.getIsprober() == Status.NO) {
                if (natInfo.getTunnetType() == RemoteProtocolType.VNC) {
                    config.setParameter("recording-name", uuid);
                } else if (natInfo.getTunnetType() == RemoteProtocolType.RDP) {
                    config.setParameter("username", natInfo.getUsername());
                    config.setParameter("ignore-cert", "true");
                    config.setParameter("security", "any");
                } else if (natInfo.getTunnetType() == RemoteProtocolType.SSH) {
                    config.setParameter("username", natInfo.getUsername());
                }
            } else {

                if (natInfo.getTunnetType() == RemoteProtocolType.VNC) {
                    config.setParameter("recording-name", uuid);
                } else if (natInfo.getTunnetType() == RemoteProtocolType.RDP) {
                    config.setParameter("username", natInfo.getUsername());
                    config.setParameter("ignore-cert", "true");
                    config.setParameter("security", "any");
                } else if (natInfo.getTunnetType() == RemoteProtocolType.SSH) {
                    config.setParameter("username", natInfo.getUsername());
                }
            }

            GuacamoleSocket socket = new ConfiguredGuacamoleSocket(new InetGuacamoleSocket(GUAC_HOSTNAME, GUAC_PORT), config);
            return new SimpleGuacamoleTunnel(socket);
        } catch (Throwable e) {
            throw new GuacamoleException(e);
        }
    }

    /**
     * 获取url参数
     * 
     * @param queryString
     * @return
     */
    private Map<String, String> getParams(String queryString) {
        Map<String, String> ret = new HashMap<String, String>();
        String[] paramsList = queryString.split("&");
        for (String item : paramsList) {
            String[] keyval = item.split("=");
            ret.put(keyval[0], keyval[1]);
        }
        return ret;
    }

    @Override
    public void onClose(Session session, CloseReason closeReason) {
        super.onClose(session, closeReason);

        Map<String, String> params = getParams(session.getQueryString());
        if (params.isEmpty()) {
            return;
        }

        String uuid = params.get("uuid");
        if (StringUtils.isEmpty(uuid)) {
            return;
        }

        NatInfo tempNatInfo = remotecpeService.getNatInfoByUUID(uuid);
        if (tempNatInfo.getIsprober() == Status.YES) {
            natService.gcPortByUUID(uuid);
            fileService.clearFilesByUuid(uuid);
        } else {
            tempNatInfo = virtulNatService.getNatInfoByUUID(uuid);
        }

        auditVideoService.addAuditVideo(tempNatInfo);
        virtulNatService.gcVirtualNatInfoByUUID(uuid);
    }

}
